package com.oot2d.event;

import com.oot2d.util.API;
import com.oot2d.util.Timer;
import com.oot2d.util.WorldManager;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;

//Provides hooks and functions for Python scripts to manipulate the game
public class EventManager {
    private static PythonInterpreter interp;
    private static ArrayList<Timer> timers;
    private LinkedList<Action> actions;
    private Action currentAction;

    public EventManager()
    {
        actions = new LinkedList<Action>();
        currentAction = null;
    }

    public static void init()
    {
        timers = new ArrayList<Timer>();
        PythonInterpreter.initialize(System.getProperties(), System.getProperties(), new String[0]);
        interp = new PythonInterpreter();

        compileScripts();
    }

    //Runs execfile() for each Python script in order to compile them for later use
    private static void compileScripts()
    {
        ArrayList<File> scripts = new ArrayList<File>();
        LinkedList<File> directories = new LinkedList<File>();
        File base = new File("res/scripts/");
        File[] files = base.listFiles();

        do {
            if (files != null) {
                for (File f : files) {
                    if (f.getName().endsWith(".py"))
                        scripts.add(f);
                    else if (f.isDirectory())
                        directories.add(f);
                }
            }

            if (directories.size() != 0)
                files = directories.pop().listFiles();
        } while (directories.size() != 0);

        for (File f : scripts) {
            System.out.println("Compiling script... " + f.getName());
            interp.execfile(f.getPath());
        }
    }

    //Call a Jython function
    public static void runScript(String file, String fun)
    {
        //long now = System.currentTimeMillis();
        interp.set("world", WorldManager.currentWorld);
        interp.set("api", API.instance);
        interp.execfile("res/scripts/" + file + ".py");
        PyObject func = interp.get(fun);
        func.__call__();
        //long then = System.currentTimeMillis();
        //System.out.println("Execution time: " + (then - now));
    }

    public static void runScript(int npcid, String file, String fun)
    {
        interp.set("npc", npcid);
        runScript(file, fun);
    }

    //Run a script by string, used from the console for debugging
    public static void runScript(String s)
    {
        interp.set("world", WorldManager.currentWorld);
        interp.set("api", API.instance);
        try {
            interp.exec("from com.oot2d import *\napi." + s);
        } catch (Exception e) {
            System.err.println("Invalid script");
        }
    }

    public void addEvent(Action e)
    {
        actions.add(e);
    }

    public void checkEvents()
    {
        if (currentAction == null && actions.size() == 0)
            return;

        if (((currentAction != null && currentAction.isDone()) || currentAction == null)) {
            if (!actions.isEmpty()) {
                //Pop the next event off the queue
                currentAction = actions.pop();
                currentAction.exec();
            } else {
                currentAction = null;
            }
        }
    }

    public boolean empty()
    {
        return (actions.isEmpty() && currentAction == null);
    }

    public int getSize()
    {
        return actions.size();
    }

    public static Timer addTimer(long d)
    {
        timers.add(new Timer(d));
        return timers.get(timers.size() - 1);
    }

    public static void removeTimer(Timer t)
    {
        timers.remove(t);
    }

    public static void updateTimers(int d)
    {
        for (Timer t : timers)
            t.update(d);
    }
}